home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ZED3DSRC.ZIP / ZSORT.C < prev    next >
C/C++ Source or Header  |  1995-06-19  |  5KB  |  274 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <zsort.h>
  4.  
  5.  
  6.  
  7. void xform_pointcollection
  8.     (pointcollection *p,
  9.      affine *xform,
  10.      pipe_point *xpoints)
  11.     {
  12.     long x,y,z;
  13.  
  14.  
  15.     for(x=0;x<p->numpoints;x++) /* for each point... */
  16.         {
  17.         /* transform it */
  18.         affine_xform(xform,p->vertex[x].location,
  19.             xpoints[x].point.location);
  20.  
  21. #ifdef __vertexnormals__
  22.         mat_mul_vec(xpoints[x].point.normal,
  23.                     xform->m,
  24.                     p->vertex[x].normal);
  25.             /* rotate vertex normals */
  26. #endif
  27.  
  28.         xpoints[x].point.clipping=p->vertex[x].clipping;
  29.             /* copy clipping information which could be required in
  30.                a later part of the pipeline */
  31.         if(xpoints[x].point.location[2]>0)
  32.             {
  33.             xpoints[x].scr_X=div(xpoints[x].point.location[0],
  34.                                  xpoints[x].point.location[2]);
  35.             xpoints[x].scr_Y=div(xpoints[x].point.location[1],
  36.                                  xpoints[x].point.location[2]);
  37.             }
  38.         }
  39.     }
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46. pipeline *alloc_pipeline(int numpoints, int numfaces, int numindex)
  47.     {
  48.     pipeline *p;
  49.  
  50.     p=malloc(sizeof(pipeline));
  51.  
  52.     if(!p)
  53.         return 0;
  54.  
  55.     p->numfaces=numfaces;
  56.     p->numindex=numindex;
  57.     p->numpoints=numpoints;
  58.     p->pbase=malloc(sizeof(pipe_point)*numpoints);
  59.     p->fbase=malloc(sizeof(face)*numfaces);
  60.     p->ibase=malloc(sizeof(long)*numindex);
  61.     p->index1=malloc(sizeof(long)*numfaces);
  62.     p->index2=malloc(sizeof(long)*numfaces);
  63.     p->minZ=malloc(sizeof(long)*numfaces);
  64.     p->maxZ=malloc(sizeof(long)*numfaces);
  65.  
  66.     if(!p->pbase||
  67.        !p->fbase||
  68.        !p->ibase||
  69.        !p->index1||
  70.        !p->index2||
  71.        !p->minZ||
  72.        !p->maxZ
  73.        )
  74.         {
  75.         free_pipeline(p);
  76.         return 0;
  77.         }
  78.  
  79.     reset_pipeline(p);
  80.  
  81.     return p;
  82.     }
  83.  
  84.  
  85.  
  86. void free_pipeline(pipeline *p)
  87.     {
  88.     if(p)
  89.         {
  90.         if(p->pbase)
  91.             {
  92.             free(p->pbase);
  93.             p->pbase=0;
  94.             }
  95.         if(p->fbase)
  96.             {
  97.             free(p->fbase);
  98.             p->fbase=0;
  99.             }
  100.         if(p->ibase)
  101.             {
  102.             free(p->ibase);
  103.             p->ibase=0;
  104.             }
  105.         if(p->index1)
  106.             {
  107.             free(p->index1);
  108.             p->index1=0;
  109.             }
  110.         if(p->index2)
  111.             {
  112.             free(p->index2);
  113.             p->index1=0;
  114.             }
  115.         if(p->minZ)
  116.             {
  117.             free(p->minZ);
  118.             p->index1=0;
  119.             }
  120.         if(p->maxZ)
  121.             {
  122.             free(p->maxZ);
  123.             p->index1=0;
  124.             }
  125.  
  126.         p->numindex=0;
  127.         p->numpoints=0;
  128.         p->numfaces=0;
  129.         free(p);
  130.         }
  131.     }
  132.  
  133.  
  134.  
  135. void reset_pipeline(pipeline *p)
  136.     {
  137.     p->pptr=0;
  138.     p->fptr=0;
  139.     p->iptr=0;
  140.     }
  141.  
  142.  
  143.  
  144.  
  145. void cull_object(object *o, pipeline *p, affine *xform)
  146.     {
  147.     long a,b,c,x,y,z;
  148.     face *f,*g;
  149.     pipe_point *pt;
  150.     vector u;
  151.     REAL D;
  152.  
  153.     pt=p->pbase+p->pptr;
  154.  
  155.     xform_pointcollection(o->pts_data,xform,pt);
  156.  
  157.     for(a=0;a<o->pts_data->numpoints;a++)
  158.         {
  159.         pt[a].point.clipping=
  160.             o->pts_data->vertex[a].clipping;
  161.         }
  162.     f=o->face_data->face;
  163.     for(a=0;a<o->face_data->numfaces;a++,f++)
  164.         {
  165.         /* backface cull. dot product of vector from eye to a point in
  166.            face with normal vector of face */
  167.         mat_mul_vec(u,xform->m,f->normal);
  168.         D=vec_dot(u, pt[*f->index].point.location);
  169.         if(D>=floattoreal(0.0))
  170.             {
  171.             /* clip */
  172.             for(b=0;b<f->numpoints;b++)
  173.                 pt[f->index[b]].point.clipping--;
  174.             }
  175.         else
  176.             {
  177.             /* output face to pipeline */
  178.             g=p->fbase+p->fptr;
  179.  
  180.  
  181.             g->index=p->ibase+p->iptr;
  182.             g->numpoints=f->numpoints;
  183.             copyvector(g->normal,u);
  184.             g->D=D;
  185.  
  186.             for(b=0;b<f->numpoints;b++)
  187.                 g->index[b]=f->index[b]+p->pptr;
  188.  
  189.             /* update pointers */
  190.             p->iptr+=f->numpoints;
  191.             p->fptr++;
  192.             }
  193.         }
  194.  
  195.     /* now all faces are properly output and culled. we need only do
  196.        vertices now */
  197.  
  198.     p->pptr+=o->pts_data->numpoints;
  199.     }
  200.  
  201.  
  202.  
  203.  
  204. long *sort_pipeline(pipeline *p)
  205.     {
  206.     long a,b,c;
  207.     REAL A,B;
  208.     face *f;
  209.     pipe_point *pt;
  210.  
  211.     f=p->fbase;
  212.     pt=p->pbase;
  213.     for(a=0;a<p->fptr;a++,f++)
  214.         {
  215.         A=pt[f->index[0]].point.location[2];
  216.         B=A;
  217.         for(b=1;b<f->numpoints;b++)
  218.             {
  219.             c=f->index[b];
  220.             if(pt[c].point.location[2]<A)
  221.                 A=pt[c].point.location[2];
  222.             else if(pt[c].point.location[2]>B)
  223.                 B=pt[c].point.location[2];
  224.             }
  225.  
  226.         p->index1[a]=a;
  227.         p->minZ[a]=realtofixed(A);
  228.         p->maxZ[a]=realtofixed(B);
  229.         }
  230.  
  231.     bytesort(p->maxZ,p->index1,p->index2,p->fptr,0);
  232.     bytesort(p->maxZ,p->index2,p->index1,p->fptr,1);
  233.     bytesort(p->maxZ,p->index1,p->index2,p->fptr,2);
  234.     bytesort(p->maxZ,p->index2,p->index1,p->fptr,3);
  235.  
  236.     return p->index1;
  237.     }
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244.  
  245. #define getbyte(x,bitshift) (((x)>>(bitshift))&0xff)
  246.  
  247. void bytesort(long *data, long *indexin, long *indexout, long itemcount,
  248.     int bytenumber)
  249.     {
  250.     long count[257];
  251.     long a,b,c;
  252.  
  253.     for(a=0;a<=256;a++)
  254.         count[a]=0;
  255.  
  256.     bytenumber*=8;
  257.  
  258.     for(a=0;a<itemcount;a++)
  259.         {
  260.         b=getbyte(data[indexin[a]],bytenumber);
  261.         count[b+1]++;
  262.         }
  263.  
  264.     for(a=1;a<256;a++)
  265.         count[a]+=count[a-1];
  266.  
  267.     for(a=0;a<itemcount;a++)
  268.         {
  269.         b=getbyte(data[indexin[a]],bytenumber);
  270.         indexout[count[b]]=indexin[a];
  271.         count[b]++;
  272.         }
  273.     }
  274.